using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace modul2
{
    class SysIndex
    {
        [Serializable()]
        public class Index:ISerializable {
            private string sName;
            private string sType;
            private string sTable;
            private bool sUnique;
            private ArrayList sColumns;

            public Index() {
                this.Name = "";
                this.Type = "";
                this.Table = "";
                this.Unique = false;
                this.sColumns = new ArrayList();
            }

            public Index(string name,string type,bool unique,string table, string[] column)
            {
                this.Name = name;
                this.Type = type;
                this.Unique = unique;
                this.Table = table;
                this.sColumns = new ArrayList();
                for (int i = 0; i < column.Length; i++) {
                    string s =column[i].Trim('\n');
                    this.Columns.Add(s);
                }
            }

            public override string ToString()
            {
                string str = "";
                str ="NAME: "+this.Name + "\nTYPE: " +this.Type + "\nUNIQUE:";
                if (this.Unique == true)
                {
                    str += "Unique \n";
                }
                else {
                    str += "not Unique \n";
                }
                str += "TABLE: " + this.Table + "\n";
                str += "COLUMNS:\n";
                for (int i = 0; i < this.Columns.Count; i++) {
                    str += sColumns[i].ToString()+"\n";
                }
                str += "----------------";
                return str;
            }

            public string Name {
                get {
                    return this.sName; 
                }
                set {
                    this.sName = value; 
                }
            }

            public string Type
            {
                get
                {
                    return this.sType;
                }
                set
                {
                    this.sType = value;
                }
            }

            public string Table {
                get 
                { 
                    return this.sTable; 
                }
                set 
                { 
                    this.sTable = value; 
                }
            }

            public bool Unique
            {
                get
                {
                    return this.sUnique;
                }
                set
                {
                    this.sUnique = value;
                }
            }

            public string this[int Index]
            {
                get
                {
                    return (string)this.sColumns[Index];
                }
                set
                {
                    this.sColumns[Index] = value;
                }
            }

            public ArrayList Columns {
                get {
                    return this.sColumns;
                }
            }

            #region ISerializable Members

            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.AddValue("IName", this.Name);
                info.AddValue("IType", this.Type);
                info.AddValue("IUnique", this.Unique);
                info.AddValue("ITable", this.Table);
                info.AddValue("IColCount", this.Columns.Count);
                for (int i = 0; i < this.Columns.Count; i++) {
                    info.AddValue("IColumn_" + i.ToString(), this[i]);
                }
               // throw new Exception("The method or operation is not implemented.");
            }

            public Index(SerializationInfo info, StreamingContext ctxt)
            {
                this.Name = info.GetString("IName");
                this.Type = info.GetString("IType");
                this.Unique = info.GetBoolean("IUnique");
                this.Table=info.GetString("ITable");
                int c = info.GetInt32("IColCount");
                this.sColumns = new ArrayList();
                for (int i = 0; i < c; i++) { 
                    this.Columns.Add(info.GetString("IColumn_" + i.ToString()));
                }
                //Get the values from info and assign them to the appropriate properties
            }
            #endregion

            public bool FindColumn(string name) {
                foreach (string c in this.Columns) {
                    if (c == name) {
                        return true;
                    }
                }
                return false;
            }
        }

        private string aIndexFile = "";

        private ArrayList aIndexy;

        public SysIndex(string IndexFile) {
            aIndexFile = IndexFile;
            aIndexy = new ArrayList();
            this.ReadIndexFile();
        }

        private void ReadIndexFile() {
            Stream stream = File.Open(this.aIndexFile, FileMode.OpenOrCreate);
            BinaryFormatter Formater = new BinaryFormatter();
            if (stream.Length != 0)
            {
                int c = (int)Formater.Deserialize(stream);
                for (int i = 0; i < c; i++)
                {
                    aIndexy.Add((Index)Formater.Deserialize(stream));
                }
            }
            stream.Close();
        }

        private void WriteIndexFile()
        {
            Stream stream = File.Open(this.aIndexFile, FileMode.Create);
            BinaryFormatter Formater = new BinaryFormatter();
            Formater.Serialize(stream,this.aIndexy.Count);
            foreach(Index i in this.aIndexy){
                Formater.Serialize(stream, i);
            }
            stream.Close();
        }

        public bool CreateIndex(string name, string type, bool unique, string table,string[] columns)
        {
            bool res = false;
            if (this.FindOrderIndex(table,columns) == -1)
            {
                Index pom = new Index(name, type, unique, table, columns);
                this.aIndexy.Add(pom);
            }
            this.WriteIndexFile();
            return res;

        }

        public int FindOrderIndex(string table,string[] cols) {
            int ret = -1;
            int pos = 0;
            foreach (Index i in this.aIndexy) {
                bool najdene = true;
                if (i.Table == table)
                {
                    if (cols.Length == i.Columns.Count)
                    {
                        for (int j = 0; j < cols.Length; j++)
                        {
                            if (cols[j] != (i.Columns[j] as string))
                            {
                                najdene = false;
                            }
                        }
                    }
                    else
                    {
                        najdene = false;
                    }
                }
                else {
                    najdene = false;
                }
                if (najdene) {
                    ret = pos;
                }
                pos++;
            }
            return ret;
        }
        public int FindIndex(string name)
        {
            int res = -1;
            foreach (Index i in this.aIndexy) {
                res++;
                if (name==i.Name){
                    return res;
                }
            }
            return -1;
        }

        public bool DropIndex(string name) {
            bool res = false;
            int pos = this.FindIndex(name);
            if (pos != -1)
            {
                aIndexy.RemoveAt(pos);
                res = true;
            }
            this.WriteIndexFile();
            return res;
        }

        public bool IsInIndex(string name) {
            foreach (Index i in this.aIndexy) {
                if (i.FindColumn(name)) {
                    return true;
                }
            }
            return false;
        }

        public string ListIndex(string name) {
            string res = "";
            foreach (Index pom in this.aIndexy) {
                if (name == "")
                {
                    res += pom.ToString() + "\n";
                }
                else { 
                    if(pom.FindColumn(name)){
                        res += pom.ToString() + "\n";
                    }
                }
            }
            return res;
        }

        public ArrayList Columns {
            get {
                return this.aIndexy;
            }
        }

        public Index this[int Index] {
            get {
                return (Index)this.aIndexy[Index];
            }
            set {
                this.aIndexy[Index] = value;
            }
        }
    }
}
